AWS IoT Coreに権限管理を簡素化する機能が追加されました
はじめに
コンサル部の神野です。2024/11/15にAWS IoT Coreで「モノと接続の関連付け」を使って権限管理を簡素化する機能がリリースされました。
タイトルの響きだけ聞いてもピンと来なかったのですが、下記説明を見たら理解できました。
モノと接続の関連付けにより、クライアント ID がモノの名前と一致しない場合に、MQTT クライアントをレジストリのモノにマッピングできます。これにより、開発者は IoT ポリシーのレジストリ情報を活用し、デバイスのアクションをライフサイクルイベントに簡単に関連付け、カスタムコスト割り当てやリソース固有のログ記録などの既存の機能を利用できるようになります。それらの機能は、以前はクライアント ID とモノの名前を一致させるためにのみ利用可能でした。
今まではクライアントIDとモノの名前を一致させることで行えた機能が一致せずとも「モノと接続の関連付け」機能によって解決できるようになったアップデートな訳ですね。
どうやって関連付けを行うのか実際にやってみてご紹介したいと思います。
環境構築
まずは実行するために環境を作成します。
下記記事に従ってIoT Coreを試せる環境をTerraformで作成します。
コードレポジトリからpull
してそのコードを一部修正して実施する流れです。
環境作成記事
コードレポジトリ
一部変更箇所
IoT Coreのポリシーを一部既存コードから変更します。
ポリシー変数を使って、モノに証明書がアタッチされている場合のみ接続できるように変更します。
# IoTポリシーを作成
# このポリシーは特定のトピックに対する操作を許可
resource "aws_iot_policy" "pubsub" {
name = "PubSubToSpecificTopic"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
# 特定のクライアントの接続を許可
Effect = "Allow"
Action = ["iot:Connect"]
- Resource = ["arn:aws:iot:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:client/${aws_iot_thing.example.name}"]
+ Resource = ["*"]
+ Condition = {
+ Bool = {
+ "iot:Connection.Thing.IsAttached": ["true"]
+ }
+ }
},
{
# 特定のトピックへの発行と受信を許可
Effect = "Allow"
Action = ["iot:Publish", "iot:Receive"]
Resource = ["arn:aws:iot:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:topic/my/test/topic"]
},
{
# 特定のトピックフィルターへのサブスクリプションを許可
Effect = "Allow"
Action = ["iot:Subscribe"]
Resource = ["arn:aws:iot:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:topicfilter/my/test/topic"]
}
]
})
}
実行
apply
コマンドを実行して、環境に反映させます。
terraform apply
作成が完了したらリソースを確認します。
確認
対象のモノとクライアントIDが一致していることを確認します。
IoT Coreに登録されているモノの名前
example-thing
で作成されていますね。
クライアントIDの定義をしているコード
MQTTクライアントを作成する際に引数にクライアントIDを指定しています。
下記コードを見るとexample-thing
となっていますね。
# クライアントIDを引数に渡す
myMQTTClient = AWSIoTMQTTClient("example-thing")
AWS IoT Coreに登録されているモノの名前とクライアントIDがexample-thing
で一致しているので、Session Managerで簡単なPubSub通信を実行してみて、疎通できる確認してみます。
Session Managerから疎通確認
ec2-user
でログインしてiot_pubsub.py
を実行します。
sudo su --login ec2-user
python3 iot_pubsub.py
問題なく疎通できていますね!
ここからクライアントIDを変更してみて、疎通に失敗するか確認してみます。
試しにClientIDをexample-thing-rename
に変更します。
sed -i 's/example-thing/example-thing-rename/g' iot_pubsub.py
この状態で再度iot_pubsub.py
を実行します。
python3 iot_pubsub.py
クライアントIDとモノの名前が一致していないため、ポリシーに記載したモノのポリシー変数が解決できずタイムアウトが発生して接続に失敗しますね。
この状態でモノと接続の関連付けを行います。
「モノと接続の関連付け」を実施
IoT Coreの画面から関連付けを行います。
まずは、example-thing
の詳細画面に移動し、証明書タブを開きます。
この状態で対象証明書にチェックを入れてアクション
> 証明書をモノに独占的に関連付ける
を押下します。
注意画面が出て、この証明書に紐づく他デバイスは全て紐付けが解除されると記載が表示されます。今回はこのデバイスしか証明書に紐づけていないので、特に気にせず接続の関連付けを独占的にする
を押下します。
証明書と example-thing との独占的な関連付けに成功しました
と表示され、独占的プリンシパルが独占的
と表示されていればOKです!
この状態で再度Session Managerからメッセージを送信してみます!
Session Managerから疎通確認
おおお、モノの名前とクライアントIDが一致していなくても送信できるようになりましたね!
その他
今回は「モノと接続の関連付け」使ってクライアントIDとモノの名前が異なっていてもモノのポリシー変数が利用できるようになりましたが、それ以外にも下記が実現できるようになりました。
公式ドキュメントの日本語訳より引用
ライフサイクル イベント- ライフサイクル イベント (接続、切断、サブスクライブ、サブスクライブ解除など) でモノの名前を受け取ることができます。これにより、ルールなどでメッセージに含まれるモノの名前を処理できるようになります。詳細については、「ライフサイクル イベント」を参照してください。
リソース固有のログ記録- モノのグループに対してリソース固有のログ記録を設定し、定義されたモノのグループ内のすべてのモノに対して必要なログ記録設定を簡単に適用できます。詳細については、「AWS IoT でリソース固有のログ記録を設定する (CLI)」を参照してください。
コスト配分- コスト配分用のカスタム タグを使用して課金グループを作成し、これらのグループにアイテムを追加できます。詳細については、「課金グループ」を参照してください。
具体的にはライフサイクル イベント、リソース固有のログ記録、コスト配分も「モノと接続の関連付け」を使って、クライアントIDとモノの名前が異なる場合も利用できるようになります。
またライフサイクル イベント メッセージにモノの名前を含めたい場合は、逆に「モノと接続の関連付け」を行なっていないと含まれないと記載もあります。
ライフサイクル イベント メッセージにモノの名前を含めるには、IoT モノとクライアント接続に排他的関連付けが必要です。
おわりに
「モノの接続の関連付け」機能についていかがだったでしょうか。
今まではクライアントIDとモノの名前が一致していないと利用できない機能が、証明書とモノの紐付けを行うことで可能となりました。必要に応じて活用いただけるかと思います!
最後までご覧いただきありがとうございました!